home *** CD-ROM | disk | FTP | other *** search
- /* Stuff common to both the FTP server and client */
- #include <stdio.h>
- #include "machdep.h"
- #include "mbuf.h"
- #include "netuser.h"
- #include "timer.h"
- #include "tcp.h"
- #include "ftp.h"
- #include "session.h"
-
- #ifdef AMIGA
- #define UNIX 1 /* UNIX semantics work for Amiga in this module */
- #endif
-
- /* FTP data channel receive upcall handler */
- void
- r_ftpd(tcb,cnt)
- struct tcb *tcb;
- int16 cnt;
- {
- register struct ftp *ftp;
- struct mbuf *bp;
- #ifdef UNIX
- char c;
- #endif
-
- ftp = (struct ftp *)tcb->user;
- if(ftp->state != RECEIVING_STATE){
- close_tcp(tcb);
- return;
- }
- /* This will likely also generate an ACK with window rotation */
- recv_tcp(tcb,&bp,cnt);
-
- #ifdef UNIX
- while(pullup(&bp,&c,1) == 1){
- if(ftp->type == IMAGE_TYPE || c != '\r')
- putc(c,ftp->fp);
- }
- #else
- while(bp != NULLBUF){
- if(bp->cnt != 0)
- fwrite(bp->data,1,(unsigned)bp->cnt,ftp->fp);
- bp = free_mbuf(bp);
- }
- #endif
- }
- /* FTP data channel transmit upcall handler */
- void
- t_ftpd(tcb,cnt)
- struct tcb *tcb;
- int16 cnt;
- {
- struct ftp *ftp;
- struct mbuf *bp;
- char *cp;
- int c;
- #ifndef CPM
- #ifndef AMIGA
- char *cdsave,*pwd();
- #endif
- #endif
-
- ftp = (struct ftp *)tcb->user;
- if(ftp->state != SENDING_STATE){
- close_tcp(tcb);
- return;
- }
- if((bp = alloc_mbuf(cnt)) == NULLBUF){
- /* Hard to know what to do here */
- return;
- }
- cp = bp->data;
- while(cnt > 1 && (c = getc(ftp->fp)) != EOF){
- #ifdef CPM
- if(ftp->type == ASCII_TYPE && c == CTLZ)
- break; /* CTLZ is CP/M's text EOF marker */
- #endif
- #ifdef UNIX
- if(ftp->type == ASCII_TYPE && c == '\n'){
- *cp++ = '\r';
- bp->cnt++;
- cnt--;
- }
- #endif
- *cp++ = c;
- bp->cnt++;
- cnt--;
- }
- if(bp->cnt != 0)
- send_tcp(tcb,bp);
- else
- free_p(bp);
-
- if(cnt > 1){ /* EOF seen */
- #ifndef CPM
- #ifndef AMIGA
- cdsave = pwd(); /* Save current directory */
- chdir(ftp->cd); /* Switch to user's directory*/
- #endif
- #endif
- fclose(ftp->fp);
- #ifndef CPM
- #ifndef AMIGA
- chdir(cdsave); /* And back */
- free(cdsave);
- #endif
- #endif
- ftp->fp = NULLFILE;
- close_tcp(tcb);
- }
- }
- /* Allocate an FTP control block */
- struct ftp *
- ftp_create(bufsize)
- unsigned bufsize;
- {
- void ftp_delete();
- char *calloc(),*malloc();
- register struct ftp *ftp;
-
- if((ftp = (struct ftp *)calloc(1,sizeof (struct ftp))) == NULLFTP)
- return NULLFTP;
- if(bufsize != 0 && (ftp->buf = malloc(bufsize)) == NULLCHAR){
- ftp_delete(ftp);
- return NULLFTP;
- }
- ftp->state = COMMAND_STATE;
- ftp->type = ASCII_TYPE; /* Default transfer type */
- return ftp;
- }
- /* Free resources, delete control block */
- void
- ftp_delete(ftp)
- register struct ftp *ftp;
- {
- if(ftp->fp != NULLFILE)
- fclose(ftp->fp);
- if(ftp->data != NULLTCB)
- del_tcp(ftp->data);
- if(ftp->username != NULLCHAR)
- free(ftp->username);
- if(ftp->buf != NULLCHAR)
- free(ftp->buf);
- #ifndef AMIGA
- if(ftp->cd != NULLCHAR)
- free(ftp->cd);
- #endif
- if(ftp->session != NULLSESSION)
- ftp->session->type = FREE;
- free((char *)ftp);
- }
-
- #ifndef AMIGA
- /* Call getcwd(), but stick a backslash on the front (!) */
- #define CWDLEN 256 /* max path len */
-
- char *
- pwd()
- {
- char *buf,*malloc(),*getcwd();
-
- if((buf = malloc(CWDLEN+1)) == NULLCHAR)
- return NULLCHAR;
- buf[0] = '\\';
- if(getcwd(buf+1,CWDLEN) == NULLCHAR){
- free(buf);
- return NULLCHAR;
- }
- return buf;
- }
- #endif
-